#!/bin/bash

# 个人云笔记智能诊断和自动修复脚本
# Personal Cloud Notes Intelligent Diagnosis and Auto-Repair Script
# 版本: 3.0 - 融合版本

set -euo pipefail

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'

# 全局变量
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="/var/log/personal-cloud-notes-diagnose.log"
REPORT_FILE="/tmp/personal-cloud-notes-diagnosis-report.json"
INSTALL_DIR="/opt/personal-cloud-notes"
SERVICE_NAME="personal-cloud-notes"
DB_NAME="personal_cloud_notes"
ISSUES_FOUND=0
ISSUES_FIXED=0
AUTO_FIX=false
VERBOSE=false

# 诊断结果存储
declare -A DIAGNOSIS_RESULTS
declare -A REPAIR_ACTIONS

# 显示帮助信息
show_help() {
    cat << EOF
个人云笔记诊断和修复工具

用法: $0 [选项]

选项:
  -a, --auto-fix     自动修复发现的问题
  -v, --verbose      详细输出
  -r, --report-only  仅生成诊断报告，不修复
  -h, --help         显示此帮助信息

示例:
  $0                 # 仅诊断，不修复
  $0 -a              # 诊断并自动修复
  $0 -v -a           # 详细模式下诊断并修复
  $0 -r              # 仅生成诊断报告

EOF
}

# 解析命令行参数
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -a|--auto-fix)
                AUTO_FIX=true
                shift
                ;;
            -v|--verbose)
                VERBOSE=true
                shift
                ;;
            -r|--report-only)
                AUTO_FIX=false
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                echo "未知选项: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# 日志函数
log() {
    local level="$1"
    shift
    local message="$*"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    case "$level" in
        "INFO")
            echo -e "${GREEN}[INFO]${NC} $message"
            ;;
        "WARN")
            echo -e "${YELLOW}[WARN]${NC} $message"
            ;;
        "ERROR")
            echo -e "${RED}[ERROR]${NC} $message"
            ;;
        "DEBUG")
            if [[ "$VERBOSE" == "true" ]]; then
                echo -e "${BLUE}[DEBUG]${NC} $message"
            fi
            ;;
        "SUCCESS")
            echo -e "${GREEN}[SUCCESS]${NC} $message"
            ;;
        "FIX")
            echo -e "${PURPLE}[FIX]${NC} $message"
            ;;
    esac
    
    # 写入日志文件
    echo "[$timestamp] [$level] $message" >> "$LOG_FILE" 2>/dev/null || true
}

# 记录诊断结果
record_diagnosis() {
    local check_name="$1"
    local status="$2"
    local details="$3"
    local fix_action="${4:-}"
    
    DIAGNOSIS_RESULTS["$check_name"]="$status|$details"
    if [[ -n "$fix_action" ]]; then
        REPAIR_ACTIONS["$check_name"]="$fix_action"
    fi
    
    if [[ "$status" == "FAILED" ]]; then
        ((ISSUES_FOUND++))
    fi
}

# 检查系统服务状态
check_system_services() {
    log "INFO" "检查系统服务状态..."
    
    local services=("mysql" "mysqld" "nginx" "$SERVICE_NAME")
    local failed_services=()
    
    for service in "${services[@]}"; do
        if systemctl list-units --type=service | grep -q "$service.service"; then
            if systemctl is-active --quiet "$service"; then
                log "DEBUG" "服务 $service 正在运行"
                record_diagnosis "service_$service" "PASSED" "服务正在运行"
            else
                log "WARN" "服务 $service 未运行"
                failed_services+=("$service")
                record_diagnosis "service_$service" "FAILED" "服务未运行" "restart_service $service"
            fi
        else
            log "DEBUG" "服务 $service 不存在或未安装"
        fi
    done
    
    if [[ ${#failed_services[@]} -eq 0 ]]; then
        log "SUCCESS" "所有系统服务运行正常"
    else
        log "ERROR" "发现 ${#failed_services[@]} 个服务问题: ${failed_services[*]}"
    fi
}

# 检查端口监听状态
check_port_listening() {
    log "INFO" "检查端口监听状态..."
    
    local ports=(80 3000 3306)
    local failed_ports=()
    
    for port in "${ports[@]}"; do
        if netstat -tlnp 2>/dev/null | grep -q ":$port.*LISTEN"; then
            log "DEBUG" "端口 $port 正在监听"
            record_diagnosis "port_$port" "PASSED" "端口正在监听"
        else
            log "WARN" "端口 $port 未监听"
            failed_ports+=("$port")
            record_diagnosis "port_$port" "FAILED" "端口未监听" "fix_port_issue $port"
        fi
    done
    
    if [[ ${#failed_ports[@]} -eq 0 ]]; then
        log "SUCCESS" "所有端口监听正常"
    else
        log "ERROR" "发现 ${#failed_ports[@]} 个端口问题: ${failed_ports[*]}"
    fi
}

# 检查配置文件
check_configuration_files() {
    log "INFO" "检查配置文件..."
    
    local config_files=(
        "$INSTALL_DIR/.env"
        "/etc/nginx/sites-available/personal-cloud-notes"
        "/etc/systemd/system/personal-cloud-notes.service"
    )
    
    for config_file in "${config_files[@]}"; do
        local filename=$(basename "$config_file")
        if [[ -f "$config_file" ]]; then
            if [[ -r "$config_file" ]]; then
                log "DEBUG" "配置文件 $filename 存在且可读"
                record_diagnosis "config_$filename" "PASSED" "配置文件存在且可读"
                
                # 检查配置文件语法
                case "$filename" in
                    ".env")
                        check_env_config "$config_file"
                        ;;
                    "personal-cloud-notes")
                        check_nginx_config "$config_file"
                        ;;
                    "personal-cloud-notes.service")
                        check_systemd_config "$config_file"
                        ;;
                esac
            else
                log "WARN" "配置文件 $filename 存在但不可读"
                record_diagnosis "config_$filename" "FAILED" "配置文件不可读" "fix_file_permissions $config_file"
            fi
        else
            log "ERROR" "配置文件 $filename 不存在"
            record_diagnosis "config_$filename" "FAILED" "配置文件不存在" "recreate_config $config_file"
        fi
    done
}

# 检查.env配置文件
check_env_config() {
    local env_file="$1"
    local required_vars=("DB_HOST" "DB_NAME" "DB_USER" "DB_PASSWORD" "JWT_SECRET")
    local missing_vars=()
    
    for var in "${required_vars[@]}"; do
        if ! grep -q "^$var=" "$env_file"; then
            missing_vars+=("$var")
        fi
    done
    
    if [[ ${#missing_vars[@]} -eq 0 ]]; then
        log "DEBUG" ".env配置完整"
        record_diagnosis "env_config" "PASSED" ".env配置完整"
    else
        log "WARN" ".env配置缺少变量: ${missing_vars[*]}"
        record_diagnosis "env_config" "FAILED" "缺少环境变量: ${missing_vars[*]}" "fix_env_config"
    fi
}

# 检查Nginx配置
check_nginx_config() {
    local nginx_config="$1"
    
    if nginx -t -c /etc/nginx/nginx.conf 2>/dev/null; then
        log "DEBUG" "Nginx配置语法正确"
        record_diagnosis "nginx_syntax" "PASSED" "Nginx配置语法正确"
    else
        log "ERROR" "Nginx配置语法错误"
        record_diagnosis "nginx_syntax" "FAILED" "Nginx配置语法错误" "fix_nginx_config"
    fi
}

# 检查systemd配置
check_systemd_config() {
    local service_file="$1"
    
    if systemd-analyze verify "$service_file" 2>/dev/null; then
        log "DEBUG" "systemd服务配置正确"
        record_diagnosis "systemd_config" "PASSED" "systemd服务配置正确"
    else
        log "WARN" "systemd服务配置可能有问题"
        record_diagnosis "systemd_config" "FAILED" "systemd服务配置问题" "fix_systemd_config"
    fi
}

# 检查数据库连接
check_database_connection() {
    log "INFO" "检查数据库连接..."
    
    # 检查MySQL服务
    if ! systemctl is-active --quiet mysql && ! systemctl is-active --quiet mysqld; then
        log "ERROR" "MySQL服务未运行"
        record_diagnosis "database_service" "FAILED" "MySQL服务未运行" "restart_service mysql"
        return
    fi
    
    # 读取数据库配置
    local db_host db_user db_password
    if [[ -f "$INSTALL_DIR/.env" ]]; then
        db_host=$(grep "^DB_HOST=" "$INSTALL_DIR/.env" | cut -d'=' -f2)
        db_user=$(grep "^DB_USER=" "$INSTALL_DIR/.env" | cut -d'=' -f2)
        db_password=$(grep "^DB_PASSWORD=" "$INSTALL_DIR/.env" | cut -d'=' -f2)
    else
        log "ERROR" "无法读取数据库配置"
        record_diagnosis "database_config" "FAILED" "无法读取数据库配置" "recreate_env_config"
        return
    fi
    
    # 测试数据库连接
    if mysql -h"$db_host" -u"$db_user" -p"$db_password" -e "SELECT 1;" "$DB_NAME" >/dev/null 2>&1; then
        log "SUCCESS" "数据库连接正常"
        record_diagnosis "database_connection" "PASSED" "数据库连接正常"
        
        # 检查数据库架构
        check_database_schema "$db_host" "$db_user" "$db_password"
    else
        log "ERROR" "数据库连接失败"
        record_diagnosis "database_connection" "FAILED" "数据库连接失败" "fix_database_schema"
    fi
}

# 检查数据库架构
check_database_schema() {
    local db_host="$1"
    local db_user="$2"
    local db_password="$3"
    
    log "DEBUG" "检查数据库架构..."
    
    # 检查关键表是否存在
    local tables=("users" "notes" "files" "tags" "note_tags" "settings" "activity_logs")
    local missing_tables=()
    
    for table in "${tables[@]}"; do
        if ! mysql -h"$db_host" -u"$db_user" -p"$db_password" "$DB_NAME" -e "DESCRIBE $table;" >/dev/null 2>&1; then
            missing_tables+=("$table")
        fi
    done
    
    if [[ ${#missing_tables[@]} -eq 0 ]]; then
        log "DEBUG" "数据库架构完整"
        record_diagnosis "database_schema" "PASSED" "数据库架构完整"
    else
        log "WARN" "数据库缺少表: ${missing_tables[*]}"
        record_diagnosis "database_schema" "FAILED" "数据库缺少表: ${missing_tables[*]}" "fix_database_schema"
    fi
}

# 检查文件权限
check_file_permissions() {
    log "INFO" "检查文件权限..."
    
    local paths=(
        "$INSTALL_DIR"
        "$INSTALL_DIR/uploads"
        "$INSTALL_DIR/logs"
        "$INSTALL_DIR/.env"
    )
    
    for path in "${paths[@]}"; do
        if [[ -e "$path" ]]; then
            local owner=$(stat -c '%U' "$path" 2>/dev/null || echo "unknown")
            local perms=$(stat -c '%a' "$path" 2>/dev/null || echo "000")
            
            log "DEBUG" "$path - 所有者: $owner, 权限: $perms"
            
            # 检查关键文件的权限
            case "$(basename "$path")" in
                ".env")
                    if [[ "$perms" != "600" ]]; then
                        log "WARN" ".env文件权限不安全: $perms"
                        record_diagnosis "permissions_env" "FAILED" ".env文件权限不安全" "fix_env_permissions"
                    else
                        record_diagnosis "permissions_env" "PASSED" ".env文件权限正确"
                    fi
                    ;;
                "personal-cloud-notes"|"uploads"|"logs")
                    if [[ "$owner" != "cloudnotes" ]] && [[ "$owner" != "root" ]]; then
                        log "WARN" "$path 所有者不正确: $owner"
                        record_diagnosis "permissions_$(basename "$path")" "FAILED" "文件所有者不正确" "fix_file_ownership $path"
                    else
                        record_diagnosis "permissions_$(basename "$path")" "PASSED" "文件权限正确"
                    fi
                    ;;
            esac
        else
            log "WARN" "路径不存在: $path"
            record_diagnosis "path_$(basename "$path")" "FAILED" "路径不存在" "create_missing_path $path"
        fi
    done
}

# 检查磁盘空间
check_disk_space() {
    log "INFO" "检查磁盘空间..."
    
    local root_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
    local install_usage=$(df "$INSTALL_DIR" 2>/dev/null | awk 'NR==2 {print $5}' | sed 's/%//' || echo "$root_usage")
    
    if [[ "$root_usage" -gt 90 ]]; then
        log "ERROR" "根分区磁盘空间不足: ${root_usage}%"
        record_diagnosis "disk_space_root" "FAILED" "根分区磁盘空间不足: ${root_usage}%" "cleanup_disk_space /"
    elif [[ "$root_usage" -gt 80 ]]; then
        log "WARN" "根分区磁盘空间紧张: ${root_usage}%"
        record_diagnosis "disk_space_root" "WARNING" "根分区磁盘空间紧张: ${root_usage}%"
    else
        log "DEBUG" "根分区磁盘空间充足: ${root_usage}%"
        record_diagnosis "disk_space_root" "PASSED" "根分区磁盘空间充足: ${root_usage}%"
    fi
    
    if [[ "$install_usage" -gt 90 ]]; then
        log "ERROR" "安装目录磁盘空间不足: ${install_usage}%"
        record_diagnosis "disk_space_install" "FAILED" "安装目录磁盘空间不足: ${install_usage}%" "cleanup_disk_space $INSTALL_DIR"
    else
        log "DEBUG" "安装目录磁盘空间充足: ${install_usage}%"
        record_diagnosis "disk_space_install" "PASSED" "安装目录磁盘空间充足: ${install_usage}%"
    fi
}

# 检查内存使用
check_memory_usage() {
    log "INFO" "检查内存使用..."
    
    local mem_info=$(free | awk 'NR==2{printf "%.0f %.0f %.0f", $3/$2*100, $2/1024, $3/1024}')
    local mem_usage=$(echo "$mem_info" | awk '{print $1}')
    local mem_total=$(echo "$mem_info" | awk '{print $2}')
    local mem_used=$(echo "$mem_info" | awk '{print $3}')
    
    log "DEBUG" "内存使用: ${mem_used}MB / ${mem_total}MB (${mem_usage}%)"
    
    if [[ "${mem_usage%.*}" -gt 90 ]]; then
        log "ERROR" "内存使用率过高: ${mem_usage}%"
        record_diagnosis "memory_usage" "FAILED" "内存使用率过高: ${mem_usage}%" "optimize_memory_usage"
    elif [[ "${mem_usage%.*}" -gt 80 ]]; then
        log "WARN" "内存使用率较高: ${mem_usage}%"
        record_diagnosis "memory_usage" "WARNING" "内存使用率较高: ${mem_usage}%"
    else
        log "DEBUG" "内存使用正常: ${mem_usage}%"
        record_diagnosis "memory_usage" "PASSED" "内存使用正常: ${mem_usage}%"
    fi
}

# 检查网络连接
check_network_connectivity() {
    log "INFO" "检查网络连接..."
    
    # 检查本地回环
    if ping -c 1 127.0.0.1 >/dev/null 2>&1; then
        log "DEBUG" "本地回环连接正常"
        record_diagnosis "network_loopback" "PASSED" "本地回环连接正常"
    else
        log "ERROR" "本地回环连接失败"
        record_diagnosis "network_loopback" "FAILED" "本地回环连接失败" "fix_network_loopback"
    fi
    
    # 检查外网连接
    if ping -c 1 8.8.8.8 >/dev/null 2>&1; then
        log "DEBUG" "外网连接正常"
        record_diagnosis "network_external" "PASSED" "外网连接正常"
    else
        log "WARN" "外网连接失败"
        record_diagnosis "network_external" "FAILED" "外网连接失败" "check_network_config"
    fi
    
    # 检查DNS解析
    if nslookup google.com >/dev/null 2>&1; then
        log "DEBUG" "DNS解析正常"
        record_diagnosis "network_dns" "PASSED" "DNS解析正常"
    else
        log "WARN" "DNS解析失败"
        record_diagnosis "network_dns" "FAILED" "DNS解析失败" "fix_dns_config"
    fi
}

# 检查应用健康状态
check_application_health() {
    log "INFO" "检查应用健康状态..."
    
    # 检查应用进程
    if pgrep -f "node.*app.js" >/dev/null; then
        log "DEBUG" "应用进程运行正常"
        record_diagnosis "app_process" "PASSED" "应用进程运行正常"
    else
        log "ERROR" "应用进程未运行"
        record_diagnosis "app_process" "FAILED" "应用进程未运行" "restart_application"
    fi
    
    # 检查健康检查端点
    local max_attempts=5
    local attempt=1
    local health_ok=false
    
    while [[ $attempt -le $max_attempts ]]; do
        if curl -f -s http://localhost/health >/dev/null 2>&1; then
            health_ok=true
            break
        fi
        ((attempt++))
        sleep 1
    done
    
    if [[ "$health_ok" == "true" ]]; then
        log "SUCCESS" "应用健康检查通过"
        record_diagnosis "app_health" "PASSED" "应用健康检查通过"
    else
        log "ERROR" "应用健康检查失败"
        record_diagnosis "app_health" "FAILED" "应用健康检查失败" "restart_application"
    fi
}

# 检查前端文件
check_frontend_files() {
    log "INFO" "检查前端文件..."
    
    local frontend_files=(
        "$INSTALL_DIR/public/js/app.js"
        "$INSTALL_DIR/public/js/utils/api.js"
        "$INSTALL_DIR/public/js/utils/auth.js"
        "$INSTALL_DIR/public/js/utils/notification.js"
        "$INSTALL_DIR/public/js/components/dashboard.js"
        "$INSTALL_DIR/public/js/components/file-manager.js"
        "$INSTALL_DIR/public/index.html"
    )
    
    local missing_files=()
    
    for file in "${frontend_files[@]}"; do
        if [[ ! -f "$file" ]]; then
            missing_files+=("$(basename "$file")")
        fi
    done
    
    if [[ ${#missing_files[@]} -eq 0 ]]; then
        log "DEBUG" "前端文件完整"
        record_diagnosis "frontend_files" "PASSED" "前端文件完整"
    else
        log "WARN" "缺少前端文件: ${missing_files[*]}"
        record_diagnosis "frontend_files" "FAILED" "缺少前端文件: ${missing_files[*]}" "fix_missing_frontend_files"
    fi
    
    # 检查JavaScript语法错误
    check_javascript_syntax
}

# 检查JavaScript语法错误
check_javascript_syntax() {
    log "DEBUG" "检查JavaScript语法错误..."
    
    local js_files=(
        "$INSTALL_DIR/public/js/components/file-manager.js"
        "$INSTALL_DIR/public/js/components/dashboard.js"
        "$INSTALL_DIR/public/js/components/login.js"
    )
    
    local syntax_errors=0
    
    for file in "${js_files[@]}"; do
        if [[ -f "$file" ]]; then
            # 检查常见的语法错误
            if grep -q "}\\s*/\\*\\*" "$file"; then
                log "WARN" "发现JavaScript语法错误: $(basename "$file")"
                record_diagnosis "js_syntax" "FAILED" "$(basename "$file")存在语法错误" "fix_javascript_syntax"
                ((syntax_errors++))
            fi
        fi
    done
    
    if [[ $syntax_errors -eq 0 ]]; then
        log "DEBUG" "JavaScript语法检查通过"
        record_diagnosis "js_syntax" "PASSED" "JavaScript语法正常"
    fi
}

# 检查项目依赖
check_project_dependencies() {
    log "INFO" "检查项目依赖..."
    
    if [[ -f "$INSTALL_DIR/package.json" ]]; then
        if [[ -d "$INSTALL_DIR/node_modules" ]]; then
            log "DEBUG" "项目依赖已安装"
            record_diagnosis "project_dependencies" "PASSED" "项目依赖已安装"
        else
            log "WARN" "项目依赖未安装"
            record_diagnosis "project_dependencies" "FAILED" "项目依赖未安装" "fix_dependencies"
        fi
    else
        log "ERROR" "package.json文件不存在"
        record_diagnosis "project_dependencies" "FAILED" "package.json文件不存在" "fix_dependencies"
    fi
}

# 修复函数：重启服务
restart_service() {
    local service="$1"
    log "FIX" "重启服务: $service"
    
    if systemctl restart "$service"; then
        log "SUCCESS" "服务 $service 重启成功"
        ((ISSUES_FIXED++))
        return 0
    else
        log "ERROR" "服务 $service 重启失败"
        return 1
    fi
}

# 修复函数：修复端口问题
fix_port_issue() {
    local port="$1"
    log "FIX" "修复端口 $port 问题"
    
    case "$port" in
        80)
            restart_service nginx
            ;;
        3000)
            restart_service "$SERVICE_NAME"
            ;;
        3306)
            restart_service mysql || restart_service mysqld
            ;;
    esac
}

# 修复函数：修复文件权限
fix_file_permissions() {
    local file="$1"
    log "FIX" "修复文件权限: $file"
    
    if [[ -f "$file" ]]; then
        chmod 644 "$file"
        log "SUCCESS" "文件权限修复完成: $file"
        ((ISSUES_FIXED++))
    else
        log "ERROR" "文件不存在，无法修复权限: $file"
    fi
}

# 修复函数：修复.env文件权限
fix_env_permissions() {
    log "FIX" "修复.env文件权限"
    
    local env_file="$INSTALL_DIR/.env"
    if [[ -f "$env_file" ]]; then
        chmod 600 "$env_file"
        chown cloudnotes:cloudnotes "$env_file" 2>/dev/null || true
        log "SUCCESS" ".env文件权限修复完成"
        ((ISSUES_FIXED++))
    else
        log "ERROR" ".env文件不存在"
    fi
}

# 修复函数：修复文件所有权
fix_file_ownership() {
    local path="$1"
    log "FIX" "修复文件所有权: $path"
    
    if [[ -e "$path" ]]; then
        chown -R cloudnotes:cloudnotes "$path" 2>/dev/null || chown -R root:root "$path"
        log "SUCCESS" "文件所有权修复完成: $path"
        ((ISSUES_FIXED++))
    else
        log "ERROR" "路径不存在，无法修复所有权: $path"
    fi
}

# 修复函数：创建缺失路径
create_missing_path() {
    local path="$1"
    log "FIX" "创建缺失路径: $path"
    
    if mkdir -p "$path"; then
        chown cloudnotes:cloudnotes "$path" 2>/dev/null || true
        chmod 755 "$path"
        log "SUCCESS" "路径创建完成: $path"
        ((ISSUES_FIXED++))
    else
        log "ERROR" "路径创建失败: $path"
    fi
}

# 修复函数：重启应用
restart_application() {
    log "FIX" "重启应用服务"
    
    if systemctl restart "$SERVICE_NAME"; then
        sleep 5
        if systemctl is-active --quiet "$SERVICE_NAME"; then
            log "SUCCESS" "应用服务重启成功"
            ((ISSUES_FIXED++))
        else
            log "ERROR" "应用服务重启后仍未运行"
        fi
    else
        log "ERROR" "应用服务重启失败"
    fi
}

# 修复函数：修复数据库架构
fix_database_schema() {
    log "FIX" "修复数据库架构问题"
    
    # 读取数据库配置
    local db_host db_user db_password db_name
    if [[ -f "$INSTALL_DIR/.env" ]]; then
        source "$INSTALL_DIR/.env"
        db_host="$DB_HOST"
        db_user="$DB_USER"
        db_password="$DB_PASSWORD"
        db_name="$DB_NAME"
    else
        log "ERROR" "无法读取数据库配置"
        return 1
    fi
    
    # 创建数据库架构修复SQL
    cat > /tmp/fix_database_schema.sql << 'EOF'
-- 检查并创建完整的数据库架构

-- 创建笔记表（如果不存在）
CREATE TABLE IF NOT EXISTS notes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    content LONGTEXT,
    tags JSON,
    is_public TINYINT(1) DEFAULT 0,
    is_deleted TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL DEFAULT NULL,
    INDEX idx_user_id (user_id),
    INDEX idx_title (title),
    INDEX idx_is_deleted (is_deleted),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 创建用户表（如果不存在）
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    nickname VARCHAR(100) DEFAULT NULL,
    role ENUM('admin', 'user') DEFAULT 'user',
    avatar VARCHAR(500) DEFAULT NULL,
    storage_used BIGINT DEFAULT 0,
    storage_limit BIGINT DEFAULT 32212254720,
    is_active TINYINT(1) DEFAULT 1,
    last_login_at TIMESTAMP NULL DEFAULT NULL,
    last_login_ip VARCHAR(45) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_email (email),
    INDEX idx_role (role),
    INDEX idx_is_active (is_active)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 创建文件表（如果不存在）
CREATE TABLE IF NOT EXISTS files (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    filename VARCHAR(255) NOT NULL,
    original_name VARCHAR(255) NOT NULL,
    file_path VARCHAR(500) NOT NULL,
    file_size BIGINT NOT NULL,
    mime_type VARCHAR(100) NOT NULL,
    is_deleted TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id),
    INDEX idx_filename (filename),
    INDEX idx_is_deleted (is_deleted)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 创建标签表（如果不存在）
CREATE TABLE IF NOT EXISTS tags (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    name VARCHAR(50) NOT NULL,
    color VARCHAR(7) DEFAULT '#007bff',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY unique_user_tag (user_id, name),
    INDEX idx_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 创建笔记标签关联表（如果不存在）
CREATE TABLE IF NOT EXISTS note_tags (
    id INT AUTO_INCREMENT PRIMARY KEY,
    note_id INT NOT NULL,
    tag_id INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY unique_note_tag (note_id, tag_id),
    INDEX idx_note_id (note_id),
    INDEX idx_tag_id (tag_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 创建设置表（如果不存在）
CREATE TABLE IF NOT EXISTS settings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    setting_key VARCHAR(100) NOT NULL,
    setting_value TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY unique_user_setting (user_id, setting_key),
    INDEX idx_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 创建活动日志表（如果不存在）
CREATE TABLE IF NOT EXISTS activity_logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    action VARCHAR(100) NOT NULL,
    resource_type VARCHAR(50),
    resource_id INT,
    details JSON,
    ip_address VARCHAR(45),
    user_agent TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id),
    INDEX idx_action (action),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 创建默认管理员用户（如果不存在）
INSERT IGNORE INTO users (email, password, nickname, role, is_active, created_at) 
VALUES ('admin@123.com', '$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', '管理员', 'admin', 1, NOW());
EOF

    # 执行数据库修复
    if mysql -h"$db_host" -P"${DB_PORT:-3306}" -u"$db_user" -p"$db_password" "$db_name" < /tmp/fix_database_schema.sql; then
        log "SUCCESS" "数据库架构修复完成"
        ((ISSUES_FIXED++))
        rm -f /tmp/fix_database_schema.sql
        return 0
    else
        log "ERROR" "数据库架构修复失败"
        rm -f /tmp/fix_database_schema.sql
        return 1
    fi
}

# 修复函数：创建缺失的前端文件
fix_missing_frontend_files() {
    log "FIX" "创建缺失的前端文件"
    
    # 创建public目录结构
    mkdir -p "$INSTALL_DIR/public/js/utils" "$INSTALL_DIR/public/js/components" "$INSTALL_DIR/public/static/image"
    
    # 创建基本的JavaScript文件（如果缺失）
    if [[ ! -f "$INSTALL_DIR/public/js/app.js" ]]; then
        cat > "$INSTALL_DIR/public/js/app.js" << 'EOF'
// 基本应用配置
const API_BASE = '/api';

// 工具函数
const utils = {
    // 发送API请求
    async request(url, options = {}) {
        const token = localStorage.getItem('token');
        const headers = {
            'Content-Type': 'application/json',
            ...options.headers
        };
        
        if (token) {
            headers.Authorization = `Bearer ${token}`;
        }
        
        const response = await fetch(API_BASE + url, {
            ...options,
            headers
        });
        
        return response.json();
    },
    
    // 显示消息
    showMessage(message, type = 'info') {
        console.log(`[${type.toUpperCase()}] ${message}`);
    }
};

// 导出到全局
window.utils = utils;
EOF
        log "SUCCESS" "创建app.js文件"
    fi
    
    # 设置权限
    chown -R cloudnotes:cloudnotes "$INSTALL_DIR/public" 2>/dev/null || chown -R root:root "$INSTALL_DIR/public"
    chmod -R 755 "$INSTALL_DIR/public"
    
    log "SUCCESS" "前端文件检查完成"
    ((ISSUES_FIXED++))
}

# 修复JavaScript语法错误
fix_javascript_syntax() {
    log "FIX" "修复JavaScript语法错误"
    
    local file="$INSTALL_DIR/public/js/components/file-manager.js"
    
    if [[ -f "$file" ]] && grep -q "}\\s*/\\*\\*" "$file"; then
        # 修复file-manager.js中的语法错误
        sed -i 's/}\\s*\\/\\*\\*/}\\n\\n  \\/\\*\\*/g' "$file"
        log "SUCCESS" "修复file-manager.js语法错误"
        ((ISSUES_FIXED++))
    fi
}

# 修复函数：安装项目依赖
fix_dependencies() {
    log "FIX" "安装项目依赖"
    
    cd "$INSTALL_DIR"
    if npm install --production; then
        log "SUCCESS" "项目依赖安装完成"
        ((ISSUES_FIXED++))
        return 0
    else
        log "ERROR" "项目依赖安装失败"
        return 1
    fi
}

# 修复函数：测试API功能
test_api_functionality() {
    log "FIX" "测试API功能"
    
    # 等待服务完全启动
    sleep 5
    
    # 测试登录API
    local login_response
    login_response=$(curl -s -X POST http://localhost:3000/api/auth/login \
      -H "Content-Type: application/json" \
      -d '{"email":"admin@123.com","password":"admin123"}' 2>/dev/null || echo '{"success":false}')
    
    if echo "$login_response" | grep -q '"success":true'; then
        log "SUCCESS" "登录API测试成功"
        
        # 提取token
        local token
        token=$(echo "$login_response" | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
        
        if [[ -n "$token" ]]; then
            # 测试笔记API
            local stats_response
            stats_response=$(curl -s -X GET http://localhost:3000/api/notes/stats \
              -H "Authorization: Bearer $token" 2>/dev/null || echo '{"success":false}')
            
            if echo "$stats_response" | grep -q '"success":true'; then
                log "SUCCESS" "笔记统计API测试成功"
                ((ISSUES_FIXED++))
                return 0
            else
                log "WARN" "笔记统计API测试失败"
            fi
        fi
    else
        log "WARN" "登录API测试失败"
    fi
    
    return 1
}

# 修复函数：清理磁盘空间
cleanup_disk_space() {
    local path="$1"
    log "FIX" "清理磁盘空间: $path"
    
    # 清理日志文件
    find /var/log -name "*.log" -type f -mtime +7 -exec truncate -s 0 {} \; 2>/dev/null || true
    
    # 清理临时文件
    find /tmp -type f -mtime +7 -delete 2>/dev/null || true
    
    # 清理包管理器缓存
    if command -v apt-get >/dev/null 2>&1; then
        apt-get clean
    elif command -v yum >/dev/null 2>&1; then
        yum clean all
    fi
    
    log "SUCCESS" "磁盘空间清理完成"
    ((ISSUES_FIXED++))
}

# 生成诊断报告
generate_report() {
    log "INFO" "生成诊断报告..."
    
    local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    local hostname=$(hostname)
    
    cat > "$REPORT_FILE" << EOF
{
  "diagnosis_id": "diag_$(date +%Y%m%d_%H%M%S)",
  "timestamp": "$timestamp",
  "hostname": "$hostname",
  "platform": {
    "os": "$(uname -s)",
    "distribution": "$(lsb_release -si 2>/dev/null || echo 'Unknown')",
    "version": "$(lsb_release -sr 2>/dev/null || echo 'Unknown')"
  },
  "summary": {
    "total_checks": ${#DIAGNOSIS_RESULTS[@]},
    "issues_found": $ISSUES_FOUND,
    "issues_fixed": $ISSUES_FIXED,
    "auto_fix_enabled": $AUTO_FIX
  },
  "checks": {
EOF

    local first=true
    for check_name in "${!DIAGNOSIS_RESULTS[@]}"; do
        if [[ "$first" == "false" ]]; then
            echo "," >> "$REPORT_FILE"
        fi
        first=false
        
        local result="${DIAGNOSIS_RESULTS[$check_name]}"
        local status="${result%%|*}"
        local details="${result##*|}"
        
        cat >> "$REPORT_FILE" << EOF
    "$check_name": {
      "status": "$status",
      "details": "$details"
    }
EOF
    done

    cat >> "$REPORT_FILE" << EOF
  }
}
EOF

    log "SUCCESS" "诊断报告已生成: $REPORT_FILE"
}

# 显示诊断结果摘要
show_summary() {
    echo
    echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║                    诊断结果摘要                                ║${NC}"
    echo -e "${CYAN}║                 Diagnosis Summary                            ║${NC}"
    echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
    echo
    
    log "INFO" "诊断完成！"
    echo
    echo -e "${CYAN}统计信息:${NC}"
    echo -e "  总检查项: ${YELLOW}${#DIAGNOSIS_RESULTS[@]}${NC}"
    echo -e "  发现问题: ${RED}$ISSUES_FOUND${NC}"
    echo -e "  已修复问题: ${GREEN}$ISSUES_FIXED${NC}"
    echo -e "  剩余问题: ${YELLOW}$((ISSUES_FOUND - ISSUES_FIXED))${NC}"
    echo
    
    if [[ $ISSUES_FOUND -gt 0 ]]; then
        echo -e "${CYAN}问题详情:${NC}"
        for check_name in "${!DIAGNOSIS_RESULTS[@]}"; do
            local result="${DIAGNOSIS_RESULTS[$check_name]}"
            local status="${result%%|*}"
            local details="${result##*|}"
            
            if [[ "$status" == "FAILED" ]]; then
                echo -e "  ${RED}✗${NC} $check_name: $details"
            elif [[ "$status" == "WARNING" ]]; then
                echo -e "  ${YELLOW}⚠${NC} $check_name: $details"
            fi
        done
        echo
    fi
    
    echo -e "${CYAN}报告文件: ${YELLOW}$REPORT_FILE${NC}"
    echo -e "${CYAN}日志文件: ${YELLOW}$LOG_FILE${NC}"
    echo
    
    if [[ $ISSUES_FOUND -gt $ISSUES_FIXED ]] && [[ "$AUTO_FIX" == "false" ]]; then
        echo -e "${YELLOW}提示: 使用 -a 参数可以自动修复发现的问题${NC}"
        echo
    fi
}

# 执行修复操作
execute_repairs() {
    if [[ "$AUTO_FIX" == "false" ]] || [[ ${#REPAIR_ACTIONS[@]} -eq 0 ]]; then
        return
    fi
    
    log "INFO" "开始自动修复..."
    echo
    
    for check_name in "${!REPAIR_ACTIONS[@]}"; do
        local result="${DIAGNOSIS_RESULTS[$check_name]}"
        local status="${result%%|*}"
        
        if [[ "$status" == "FAILED" ]]; then
            local repair_action="${REPAIR_ACTIONS[$check_name]}"
            log "INFO" "修复 $check_name..."
            
            # 执行修复操作
            eval "$repair_action"
        fi
    done
    
    log "SUCCESS" "自动修复完成"
}

# 主诊断函数
run_diagnosis() {
    log "INFO" "开始系统诊断..."
    echo
    
    # 执行各项检查
    check_system_services
    check_port_listening
    check_configuration_files
    check_database_connection
    check_file_permissions
    check_disk_space
    check_memory_usage
    check_network_connectivity
    check_application_health
    
    # 检查前端文件
    check_frontend_files
    
    # 检查项目依赖
    check_project_dependencies
    
    # 执行修复（如果启用）
    execute_repairs
    
    # 生成报告
    generate_report
    
    # 显示摘要
    show_summary
}

# 显示横幅
show_banner() {
    echo -e "${CYAN}"
    cat << 'EOF'
╔══════════════════════════════════════════════════════════════╗
║                个人云笔记诊断修复工具                          ║
║           Personal Cloud Notes Diagnosis Tool               ║
║                                                              ║
║  版本: 2.0                                                   ║
║  功能: 智能诊断、自动修复、详细报告                            ║
╚══════════════════════════════════════════════════════════════╝
EOF
    echo -e "${NC}"
}

# 主函数
main() {
    # 解析命令行参数
    parse_arguments "$@"
    
    # 显示横幅
    show_banner
    
    # 检查运行权限
    if [[ $EUID -ne 0 ]]; then
        log "ERROR" "此脚本需要root权限运行"
        log "INFO" "请使用: sudo $0"
        exit 1
    fi
    
    # 创建日志文件
    touch "$LOG_FILE"
    chmod 644 "$LOG_FILE"
    
    # 运行诊断
    run_diagnosis
    
    # 返回适当的退出码
    if [[ $ISSUES_FOUND -eq 0 ]]; then
        exit 0
    elif [[ $ISSUES_FIXED -eq $ISSUES_FOUND ]]; then
        exit 0
    else
        exit 1
    fi
}

# 脚本入口点
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi